package cn.codepandas.unifiedresponse.config;

import cn.codepandas.unifiedresponse.model.ResultException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.validation.ValidationException;

/**
 * 处理异常，包括自定义异常和全局异常
 *
 * @author Amaris
 * @since 1.0.0
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    Logger logger = LoggerFactory.getLogger(getClass());

    /**
     * 处理参数校验异常
     * @param paramValidatedException 参数校验异常
     * @return 所捕获的参数校验异常
     */
    @ExceptionHandler(value = {BindException.class, ValidationException.class, ServletRequestBindingException.class})
    public Exception paramValidatedException(Exception paramValidatedException) {
        logger.error("Param Exception：{}", paramValidatedException.getMessage(), paramValidatedException);
        return paramValidatedException;
    }

    /**
     * 处理自定义结果异常
     * @param resultException 自定义异常
     * @return 所捕获的自定义结果异常
     */
    @ExceptionHandler(value = ResultException.class)
    @ResponseBody
    public ResultException resultExceptionHandler(ResultException resultException){
        logger.error("Result Exception：{}", resultException.getMessage(), resultException);
        return resultException;
    }

    /**
     * 处理其他异常
     * @param otherException 其他异常
     * @return 所捕获的其他异常
     */
    @ExceptionHandler(value = Exception.class)
    public Exception otherExceptionHandler(Exception otherException){
        logger.error("Other Exception: {}", otherException.getMessage(), otherException);
        return otherException;
    }

    /**
     * 处理其他可抛出的错误或自定义的问题
     * @param throwable 其他可抛出的错误或自定义的问题
     * @return 所捕获的错误或自定义的问题
     */
    @ExceptionHandler(value = Throwable.class)
    public Throwable errorHandle(Throwable throwable) {
        logger.error("Throwable Error: {}", throwable.getMessage(), throwable);
        return throwable;
    }

}
